package gov.pbc.nn.core.bdf.view.init;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;

import com.bstek.bdf2.core.model.UserDept;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.util.DateUtils;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.bdf.entity.User;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;

@Component
public class DeptUserInit {

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;
	@Autowired
	@Qualifier("bdf2.passwordEncoder")
	private PasswordEncoder passwordEncoder;

	@Expose
	@Transactional
	public void initDept() throws Exception {
		if(StringUtils.equalsIgnoreCase("debug", Configure.getString("core.runMode"))){
			org.springframework.core.io.Resource fileRource = new ClassPathResource(
					"gov/pbc/nn/core/bdf/view/init/dept.xls");
			Workbook deptWb = WorkbookFactory.create(fileRource.getInputStream());
			final Sheet deptSheet = deptWb.getSheetAt(0);
			this.coreHibernateDao.doInHibernateSession(new ISessionCallback<Void>() {
				
				@Override
				public Void doInSession(Session session) {
					for (int i = deptSheet.getFirstRowNum() + 1; i < deptSheet.getLastRowNum() + 1; i++) {
						Row deptRow = deptSheet.getRow(i);
						String id = getStringCellValue(deptRow, 0);
						if (StringUtils.isNotBlank(id)) {
							Dept dept = new Dept();
							dept.setId(id);
							dept.setName(getDeptName(deptRow));
							dept.setParentId(getStringCellValue(deptRow, 4));
							String level = getStringCellValue(deptRow, 5);
							dept.setDeptLevel(StringUtils.isEmpty(level) ? null : level);
							dept.setCompanyId("PBCNN");
							session.save(dept);
						}
					}
					return null;
				}
				
			});
		}

	}

	private String getStringCellValue(Row row, int columnIndex) {
		Cell cell = row.getCell(columnIndex);
		if (cell == null) {
			return null;
		}
		int type = cell.getCellType();
		if (type == Cell.CELL_TYPE_NUMERIC) {
			if (HSSFDateUtil.isCellDateFormatted(cell)) {
				return DateUtils.format("yyyy-MM-dd HH:mm:ss", cell.getDateCellValue());
			}
			Double d = new Double(cell.getNumericCellValue());
			return d.longValue() + "";
		}
		return StringUtils.trim(cell.getStringCellValue());
	}

	private String getDeptName(Row deptRow) {
		String name = getStringCellValue(deptRow, 1);
		String pname = getStringCellValue(deptRow, 7);
		String path = getStringCellValue(deptRow, 6);
		if (StringUtils.endsWith(path, "000000000")) {
			return name;
		}
		return pname + "/" + name;

	}

	@Expose
	@Transactional
	public void initUser() throws Exception {
		if(!StringUtils.equalsIgnoreCase("debug", Configure.getString("core.runMode"))){
			return;
		}
		org.springframework.core.io.Resource fileRource = new ClassPathResource(
				"gov/pbc/nn/core/bdf/view/init/user.xls");
		Workbook wb = WorkbookFactory.create(fileRource.getInputStream());
		final Sheet sheet = wb.getSheetAt(0);
		this.coreHibernateDao.doInHibernateSession(new ISessionCallback<Void>() {

			private Map<String, User> map = new HashMap<String, User>();

			@Override
			public Void doInSession(Session session) {
				int maxUsername = Integer.parseInt(generalUsername(session));
				for (int i = sheet.getFirstRowNum() + 1; i < sheet.getLastRowNum() + 1; i++) {
					Row row = sheet.getRow(i);
					String cname = getStringCellValue(row, 0);
					if (StringUtils.isNoneBlank(cname)) {
						String fkSysName = getStringCellValue(row, 4);
						System.out.println(fkSysName);
						if (this.map.containsKey(fkSysName)) {
							break;
						}
						User user = new User();
						user.setCompanyId("PBCNN");
						user.setFkSysName(fkSysName);
						user.setCname(cname);
						user.setIdentity(getStringCellValue(row, 1));
						user.setMobile(getStringCellValue(row, 3));
						user.setUsername("U" + (++maxUsername));
						user.setDuty(getStringCellValue(row, 5));
						user.setMale(StringUtils.equals(getStringCellValue(row, 6), "男"));
						try {
							user.setBirthday(DateUtils.parse("yyyy-MM-dd HH:mm:ss", getStringCellValue(row, 7)));
						} catch (ParseException e) {
							e.printStackTrace();
						}
						int salt = RandomUtils.nextInt(1000);
						user.setSalt(String.valueOf(salt));
						String password = Configure.getString("default.password");
						user.setPassword(passwordEncoder.encodePassword(password, salt));
						session.save(user);

						UserDept ud = new UserDept();
						ud.setId(UUID.randomUUID().toString());
						ud.setDeptId(getStringCellValue(row, 13));
						ud.setUsername(user.getUsername());
						session.save(ud);

						this.map.put(user.getFkSysName(), user);
					}
				}
				return null;
			}

		});
	}

	private String generalUsername(Session session) {
		String sql = "select max(u.USERNAME_) from t_user u where u.USERNAME_ REGEXP '^U[0-9]+$'";
		String maxUsername = (String) session.createSQLQuery(sql).uniqueResult();
		if (StringUtils.isEmpty(maxUsername)) {
			maxUsername = "99999";
		} else {
			maxUsername = String.valueOf(Long.parseLong(maxUsername.substring(1)));
		}
		return maxUsername;
	}

	public static void main(String[] args) throws Exception {
		DeptUserInit init = new DeptUserInit();
		init.initDept();
	}
}
